﻿using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

namespace CWM.Skinn
{
    public static partial class SkinnContextCommands
    {
        [CtxMenuItem("Transform/Cache/Store Local", "Stores local transformation(s) for use later." +
            "Works in and out of play mode.", 0)]
        public static void TransformStore()
        {
            foreach (var item in SkinnContext.GetContextItems())
            {
                var context = item.GetComponent<Transform>();
                if (SkinnEx.IsNullOrNotInAScene(context)) return;
                LocalTransformUtility.StoreTransform(context);
            }
            SkinnContext.Finished();

        }

        [CtxMenuItem("Transform/Cache/Load Local", "Apply transformation(s) stored with the Store Command.", 0)]
        public static void TransformLoad()
        {
            foreach (var item in SkinnContext.GetContextItems())
            {
                var context = item.GetComponent<Transform>();
                if (SkinnEx.IsNullOrNotInAScene(context)) continue;

                Undo.RecordObject(context, "Load Transform");
                LocalTransformUtility.LoadTransform(context);
            }
            SkinnContext.Finished();

        }

        private static class LocalTransformUtility
        {
            public static void StoreTransform(Transform context)
            {
                if (!SkinnInternalAsset.Asset) return;
                if (SkinnEx.IsNullOrNotInAScene(context)) return;
                var data = SkinnInternalAsset.Asset.transforms;
                int hashId = context.gameObject.GetInstanceID();
                int index = data.FindIndex((a) => { return a.hashID == hashId; });
                if (index < 0)data.Add(new LocalTransform(context));
                else data[index].Set(context);
                SkinnInternalAsset.Asset.transforms = data;
                Refresh();
            }

            public static void LoadTransform(Transform context)
            {
                if (!SkinnInternalAsset.Asset) return;
                if (SkinnEx.IsNullOrNotInAScene(context)) return;
                Refresh();
                var data = SkinnInternalAsset.Asset.transforms;
                int hashId = context.gameObject.GetInstanceID();
                int index = data.FindIndex((a) => { return a.hashID == hashId; });
                if (index < 0) return;
                context.localPosition = data[index].localPosition;
                context.localRotation = data[index].localRotation;
                context.localScale = data[index].localScale;
            }

            private static void Refresh()
            {
                List<LocalTransform> data = SkinnInternalAsset.Asset.transforms;
                var newData = new List<LocalTransform>(data.Count);
                for (int i = 0; i < data.Count; i++)
                {
                    if (SkinnEx.FindGameObject(data[i].hashID)) newData.Add(data[i]);
                }
                SkinnInternalAsset.Asset.transforms = newData;
                EditorUtility.SetDirty(SkinnInternalAsset.Asset);
            }
        }
    }
}